package com.qf.shiro.base.realm;

import com.qf.shiro.base.entity.SysUser;
import com.qf.shiro.base.service.RoleService;
import com.qf.shiro.base.service.SysUserService;
import com.qf.shiro.base.vo.SysOperationVo;
import com.qf.shiro.base.vo.SysRoleVo;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

public class UserRealm extends AuthorizingRealm {
    @Resource
    private SysUserService sysUserService;

    /**
     * 移动端     jsessionId
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //用户输入的用户名
        String username = (String) token.getPrincipal();
        SysUser userInfo = sysUserService.getUserInfo(username);
        if (ObjectUtils.isEmpty(userInfo)) {
            throw new UnknownAccountException();
        }
        if (userInfo.getDelStatus() != 0) {
            throw new LockedAccountException();
        }
        //  vo对象
        /*
         * Object principal,  从数据中获取的对向
         * Object hashedCredentials,  数据中的密码
         * ByteSource credentialsSalt,  加密盐
         * String realmName   用户名
         */
        return new SimpleAuthenticationInfo(userInfo, userInfo.getPassword(), null, username);
    }


    /**
     * 从数据中获取权限数据
     *
     * @param principals 认证接口的用户对象
     * @return
     */
    @Resource
    private RoleService roleService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 获取认证用户对象
        SysUser sysUser = (SysUser) principals.getPrimaryPrincipal();
        List<SysRoleVo> sysRoleVos = roleService.queryRoles(sysUser.getUserId());
//        stream流
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //添加角色数据
        authorizationInfo.setRoles(sysRoleVos.stream().map(SysRoleVo::getRoleName).collect(Collectors.toSet()));
        //添加权限数据
        authorizationInfo.setStringPermissions(sysRoleVos.stream().flatMap(sysRoleVo -> sysRoleVo.getOperationList().stream().map(SysOperationVo::getOperationName)).collect(Collectors.toSet()));
        return authorizationInfo;
    }
}
